﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MathService.DSP.Signals.Service
{
    [Serializable]
    public enum UpDownDirection : byte { Up = 0, Down = 1 }

    [Serializable]
    public class FrontFinder
    {
        [Serializable]
        public struct Front
        {
            public double Delta;
            public int Step;
            public int Position;

            public UpDownDirection FrontType
            {
                get { return Delta > 0 ? UpDownDirection.Up : UpDownDirection.Down; }
            }

            public double Derivative { get { return Delta / (double)Step; } }


            public Front(double Delta, int Position, int Step)
            {
                this.Delta = Delta;
                this.Position = Position;
                this.Step = Step;
            }
        }

        private double f_Treshold = 0;

        public double Treshold { get { return f_Treshold; } set { f_Treshold = value; } }

        public FrontFinder() { }

        public FrontFinder(double Treshold)
        {
            f_Treshold = Treshold;
        }


        public Front[] GetFronts(double[] array, int Step)
        {                
            if(Step < 1) throw new ArgumentOutOfRangeException("Шаг должен быть > 1");

            List<Front> Fronts = new List<Front>();

            for(int i = 0; i < array.Length - Step; i+= Step)
            {
                double Delta = array[i + Step] - array[i];
                if(Delta.GetAbs() >= f_Treshold)
                    Fronts.Add(new Front(Delta, i, Step));
            }                
            return Fronts.ToArray();
        }

        public Front[] GetFronts(DigitalSignal Signal, int Step)
        {
            return GetFronts(Signal.Samples, Step);
        }

        public Front[] GetFronts(DigitalSignal Signal, double Step)
        {
            if(Step < double.Epsilon)
                throw new ArgumentOutOfRangeException("Шаг должен быть > " + double.Epsilon.ToString());

            List<Front> Fronts = new List<Front>();
            int intStep = (int)(Step / Signal.dx);
            double s1 = 0, s0 = Signal[0];
            for(double x = Signal.x0 + Step, x1 = Signal.x1 - Step; x < x1; x += Step)
            {
                s1 = Signal[x];
                double Delta = s1 - s0;
                s0 = s1;
                if(Delta.GetAbs() >= f_Treshold)
                    Fronts.Add(new Front(Delta, Signal.SamplePos(x - Step), intStep));
            }

            return Fronts.ToArray();
        }
    }
}
